//= require <configurable>
Selectbox = Class.create(Configurable, {
    body_node_ : '',
    initialize: function(options) 
    {
        this.setOptions(options);
        this.run();
    },
    run : function()
    {
        $$('body').each(function(body){
            body.writeAttribute({'role': 'application'});
            this.body_node_ = body;
        }.bind(this));
        $$('select.' + this.options.class_name).each(function(element){
            this.createSelectList(element);
            this.createMenuLink(element);
            element.hide().writeAttribute({'aria-hidden': 'true'});
            var id = element.readAttribute('id') + '-' + this.options.link_name;
            $$('label[for="'+element.readAttribute('id')+'"]').each(function(label){
                label.writeAttribute({'for': id});
            }.bind(id));
        }.bind(this));
        this.body_node_.observe('click', this.checkList.bindAsEventListener(this));
    },
    createSelectList : function(element)
    {
        //var offset = element.viewportOffset();
        var offset = element.cumulativeOffset();
        var list = '<ul id="' + element.readAttribute('id') + '-' + this.options.link_name + '-menu" aria-labelledby="' + element.readAttribute('id') + '-' + this.options.link_name + '" aria-hidden="true" role="listbox" class="selectbox-menu" style="display: none; left: '+offset.left+ 'px; top:'+ (offset.top+element.getHeight())+ 'px;">';
        element.childElements().each(function(listitem){
            list += '<li';
            if(listitem.selected)
                list +=' aria-selected="true"';
            list += '><a href="#" role="option">'+listitem.innerHTML+'</a><span class="option-value skip">'+listitem.readAttribute('value')+'</span></li>';
        }.bind(list));
        this.body_node_.insert({'bottom' : list});
        if($(element.readAttribute('id') + '-' + this.options.link_name + '-menu').select('[aria-selected="true"]').length == 0)
            $(element.readAttribute('id') + '-' + this.options.link_name + '-menu').firstDescendant().writeAttribute({'aria-selected' : 'true'});
    },
    createMenuLink : function(element)
    {
        var s_option;
        $(element.readAttribute('id') + '-' + this.options.link_name + '-menu').select('[aria-selected="true"]').each(function(option){
            s_option = option;
        }.bind(s_option));
        var link = '<a id="' + element.readAttribute('id') + '-' + this.options.link_name + '" href="#" class="custom-select group" aria-haspopup="true" role="button" aria-owns="'+element.readAttribute('id') + '-' + this.options.link_name + '-menu"><span class="custom-select-text">'+s_option.firstDescendant().innerHTML+'</span><span class="custom-select-button-icon"></span>';
        element.insert({after: link});
    },
    checkList : function(event)
    {
        if(!this.catchButtonEvent(event) && !this.updateMenu(event))
            this.hideOpenMenus(event);
    },
    catchButtonEvent : function(event)
    {
        var menu, element;
        element = event.findElement('a.custom-select');
        if(element == null || element == document)
            return false;
        event.stop();
        menu = $(element.readAttribute('id')+'-menu');
        this.toggleMenu(menu);
        return true;
    },
    toggleMenu : function(menu)
    { 
        if(menu.getStyle('display') == 'none')
        {
            menu.show();
            menu.writeAttribute({'aria-hidden' : 'false'});
            var element = $(menu.readAttribute('aria-labelledby'));
            var offset = element.cumulativeOffset();
            menu.setStyle({left: offset.left+'px', top: (offset.top+element.getHeight())+'px'});
        }
        else
        {
            menu.hide();
            menu.writeAttribute({'aria-hidden': 'true'});
        }
    },
    updateMenu : function(event)
    {
        var element = event.findElement('ul.selectbox-menu li a');
        if(element == null || element == document)
            return false;
        event.stop();
        var menu = element.up().up();
        if(menu.readAttribute('id') == null)
            return false;
        $$('a[aria-owns="'+menu.readAttribute('id')+'"]').each(function(link){
            link.firstDescendant().innerHTML = element.innerHTML;
        }.bind(element));
        $$('#'+menu.readAttribute('id')+' li[aria-selected="true"]').each(function(link){
            link.writeAttribute({'aria-selected' : 'false'});
        });
        element.up().writeAttribute({'aria-selected' : 'true'});
        var id = element.up().up().readAttribute('id').gsub('-' + this.options.link_name + '-menu', '');
        var option_value = element.up().select('.option-value').first().innerHTML;
        $(id).select('option[selected]').first().selected = false;
        $(id).select('option[value="'+option_value+'"]').first().selected=true;
        this.toggleMenu(menu);
        return element.next().innerHTML;
    },
    hideOpenMenus : function(event)
    {
        $$('ul[aria-hidden="false"]').each(function(menu){
            this.toggleMenu(menu);
        }.bind(this));
    }
});

Selectbox.DEFAULT_OPTIONS = {
    class_name: 'selectbox',
    link_name: 'button'
};
